<?php
/**
 * Inter框架核心文件之对象仓库、对象注册表
 * 存放框架运行中所产生的实例、或者需要共享的变量等。
 * 本组件依赖性：可独立使用。
 * 本文件的思路参考过以下程序，在此一并致谢！
 *     - PHP框架Zend Framework{@link http://framework.zend.com/}
 * 
 * @author Horse Luke<horseluke@126.com>
 * @copyright Horse Luke, 2010
 * @license the Apache License, Version 2.0 (the "License"). {@link http://www.apache.org/licenses/LICENSE-2.0}
 * @version $Id: Registry.php 115 2010-06-27 11:19:54Z horseluke@126.com $
 * @package Inter_PHP_Framework
 */

class Inter_Registry extends ArrayObject
{
    /*
     * 保存对象仓库的实例，必须是Inter_Registry 类实例
     *
     * @var Inter_Registry Inter_Registry 类实例
     */
    private static $_registryInstance = null;
    
    /*
     * 保存对象仓库的名称
     *
     * @var string
     */
    private static $_registryClassName='Inter_Registry';
    
    /**
     * 保存一个东西到对象仓库中，静态化操作
     *
     * @param string $index 索引键值（也就是要保存的东西的“标签”）
     * @param mixed $value 要保存的东西
     */
    public static function set($index,$value){
        $instance = self::getInstance();
        $instance->offsetSet($index, $value);
    }
    
    /**
     * 按照索引键值取得对象仓库中的东西
     *
     * @param string $index 索引键值（也就是要保存的东西的“标签”）
     * @param bool $forceException 当指定键值没有内容时，是否强制抛出Exception。默认为false（此时将返回空值null），true则抛出。
     * @return mixed 存储的东西
     */
    public static function get($index, $forceException = false){
        $instance = self::getInstance();
        if ($instance->offsetExists($index)) {
            return $instance->offsetGet($index);
        }elseif(false == $forceException){
            return null;
        }else{
            throw new Exception("No entry is registered for key '$index'");
        }
    }
    
    /**
     * 取得一个实例，没有则通过静态方法init()构造一个Inter_Registry 类实例
     *
     * @return Inter_Registry Inter_Registry 类实例
     */
    public static function getInstance(){
        if(null === self::$_registryInstance){
            self::init();
        }
        return self::$_registryInstance;
    }
    
    /**
     * 这是一个protected的初始化方法，用于通过$_registryClassName名称构造一个Inter_Registry 类实例
     *
     */
    protected static function init(){
        self::setInstance(new self::$_registryClassName());
    }
    
    /**
     * 保存一个Inter_Registry 类实例到静态属性$_registryInstance中
     *
     * @param Inter_Registry $registry Inter_Registry 类实例
     */
    public static function setInstance(Inter_Registry $registry){
        if(null !== self::$_registryInstance){
            throw new Exception('Registry is already initialized');
        }
        self::setClassName(get_class($registry));
        self::$_registryInstance = $registry;
    }
    
    /**
     * 设置静态属性$_registryClassName的名称
     *
     * @param string $registryClassName
     */
    public static function setClassName($registryClassName = 'Inter_Registry'){
        if (self::$_registryInstance !== null) {
            throw new Exception('Registry is already initialized');
        }

        if (!is_string($registryClassName)) {
            throw new Exception("Argument is not a class name");
        }

        self::$_registryClassName = $registryClassName;
    }

    /**
     * 销毁保存在静态属性$_registryInstance中的Inter_Registry对象
     *
     */
    public static function _unsetInstance(){
        self::$_registryInstance = null;
    }
    
    /**
     * Zend_FrameWork：
     * Constructs a parent ArrayObject with default
     * ARRAY_AS_PROPS to allow acces as an object
     *
     * @param array $array data array
     * @param integer $flags ArrayObject flags
     */
    public function __construct($array = array(), $flags = parent::ARRAY_AS_PROPS){
        parent::__construct($array, $flags);
    }
    
    /**
     * 重写ArrayObject的方法offsetExist()
     *
     * @param string $index
     * @return mixed
     */
    public function offsetExists($index){
        return array_key_exists($index, $this);
    }
    
}
